﻿@using StackExchange.Opserver.Views.Elastic
@model DashboardModel
@{
    Layout = null;
}
@foreach (var c in Model.Clusters.Where(c => c.Nodes.Data != null && c.Nodes.Data.Nodes != null && c.Nodes.Data.Nodes.Any()))
{
    var ss = c.ShardStates;
    var hs = c.HealthStatus.SafeData(true);
    var ns = c.Nodes.SafeData(true);
    <table class="node-dashboard cluster-dashboard">
        <tbody class="node-header" data-name="header-@c.UniqueKey-@ns.Name">
            <tr class="category-row">
                <th colspan="12">
                    <h3>@hs.IconSpan() @ns.Name 
                        <span class="cluster-info">
                            (@ns.Nodes.Count.Pluralize("node"), @ss.Count().ToComma() @ss.Count().Pluralize("shard", includeNumber: false)@if (hs.InitializingShards > 0) {<text>, <b>@hs.InitializingShards.ToComma() initializing</b></text>}@if (hs.RelocatingShards > 0){<text>, <b>@hs.RelocatingShards.ToComma() relocating</b></text>}@if (hs.UnassignedShards > 0){<text>, <b>@hs.UnassignedShards.ToComma() unassigned</b></text>})
                        </span>
                    </h3>
                </th>
            </tr>
            <tr>
                <th></th>
                <th>Node</th>
                <th>Shards</th>
                <th>CPU</th>
                <th>Memory</th>
                <th>Virtual</th>
                <th>Indexes</th>
                <th>Searches</th>
                <th>Conns</th>
                <th>Rx</th>
                <th>Tx</th>
                <th>As of</th>
            </tr>
        </tbody>
        <tbody class="node-group" data-name="@c.UniqueKey-@ns.Name">
            @foreach (var n in ns.Nodes)
            {
                var shards = ss.Where(sh => sh.Node == n.GUID);
                var upTime = DateTime.UtcNow.AddMilliseconds(-n.Stats.JVM.UptimeInMilliseconds);
                <tr class="@n.RowClass()">
                    <td>@n.IconSpan()</td>
                    <td title="Up since @upTime.ToUniversalTime() (@upTime.ToRelativeTime())">
                        <a href="/elastic/node?cluster=@c.Name.UrlEncode()&node=@n.Name.UrlEncode()">@n.Name</a>
                    </td>
                    <td>@shards.Count().ToComma() (@shards.Count(s => s.Primary) primary)</td>
                    @if (n.Stats != null && n.Stats.Process != null && n.Stats.Process.CPU != null)
                    {
                        <td title="Process CPU: @n.Stats.Process.CPU.Percent.ToComma()%
@if (n.Stats.OS.LoadAverage != null) {<text>Load average: @(string.Join(",", n.Stats.OS.LoadAverage))</text>}">@((n.Stats.OS.CPU.User + n.Stats.OS.CPU.System).ToComma())%</td>
                    }
                    else
                    {
                    <td class="note">n/a</td>
                    }
                    @if (n.Stats != null && n.Stats.Process.Memory != null)
                    {
                    <td>@n.Stats.Process.Memory.ResidentInBytes.ToSize("b")</td>
                    <td>@n.Stats.Process.Memory.TotalVirtualInBytes.ToSize("b")</td>
                    }
                    else
                    {
                    <td class="note">n/a</td>
                    <td class="note">n/a</td>
                    }
                    <td title="@c.HealthStatus.Data.Indices.Count.ToComma() indexes with @(n.Stats.Process.OpenFileDescriptors.ToComma()) open file descriptors">
                        <a href="/elastic/indices?cluster=@c.Name&node=@n.Name">
                            @c.HealthStatus.Data.Indices.Count.ToComma()
                        </a> <span class="note">@(n.Stats.Indices.Store.SizeInBytes > 0 ? "(" + n.Stats.Indices.Store.SizeInBytes.ToSize("b") + ")" : "")</span>
                    </td>
                    <td>@n.Stats.Indices.Search.QueryTotal.ToComma()</td>
                    @if (n.Stats.HTTP != null)
                    {
                    <td title="@n.Stats.HTTP.CurrentOpen open, @n.Stats.HTTP.TotalOpened.ToComma() total">@n.Stats.HTTP.CurrentOpen.ToComma()</td>
                    }
                    else
                    {
                    <td><span class="note">n/a</span></td>
                    }
                    <td>@n.Stats.Transport.RXSizeInBytes.ToSize("b")</td>
                    <td>@n.Stats.Transport.TXSizeInBytes.ToSize("b")</td>
                    <td>@c.Status.ToPollSpan()</td>
                </tr>
            }
            @if (c.SettingsNodes.Count > ns.Nodes.Count)
            {
                <tr class="critical-row centered">
                    <td colspan="12">@((c.SettingsNodes.Count - ns.Nodes.Count).Pluralize("node")) currently missing of (@string.Join(", ", c.SettingsNodes.Select(s => s))).</td>
                </tr>
            }
        </tbody>
    </table>
}
<div class="cluster-sub-detail">
@if (Model.Clusters.Any(c => c.TroubledIndexes.Any()))
{
    <div class="node-dashboard-separator"></div>
    @Html.Partial("Dashboard.Cluster.Indices", Model)
}
@if (Model.Clusters.Any(c => c.TroubledShards.Any()))
{
    <div class="node-dashboard-separator"></div>
    @Html.Partial("Dashboard.Cluster.Shards", Model)
}
</div>